%=============================================================================
% File:  graphz.tex --  Library for plotting networks in TikZ
% Author(s): Jürgen Hackl <hackl@ibi.baug.ethz.ch>
% Creation:  28 Feb 2017
% Time-stamp: <Son 2017-08-27 11:18 juergen>
%
% Copyright (c) 2017 Jürgen Hackl <hackl@ibi.baug.ethz.ch>
%               http://www.ibi.ethz.ch
% $Id$
%
% More information on LaTeX: http://www.latex-project.org/
% LaTeX symbol list: 
%   http://www.ctan.org/tex-archive/info/symbols/comprehensive/symbols-a4.pdf
%=============================================================================

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{tkz-network}

%=============================================================================
%     Used packages
%=============================================================================
\RequirePackage{etex}
\RequirePackage{xifthen}
\RequirePackage{xkeyval}[2005/11/25]
\RequirePackage{tikz}
\RequirePackage{datatool}
\usetikzlibrary{arrows}  
\usetikzlibrary{positioning}
\usetikzlibrary{3d}
\usetikzlibrary{fit}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}

%=============================================================================


%=============================================================================
%      Predefined variables
%=============================================================================

%<--------------------------------------------------------------------------->
%      Vertex
%<--------------------------------------------------------------------------->
\definecolor{vertexfill}{HTML}{abd7e6}
\newcommand*{\DefaultUnit}{cm}
\newcommand*{\DistanceScale}{1}

\newcommand*{\VertexShape}{circle}
\newcommand*{\VertexInnerSep}{2pt}
\newcommand*{\VertexOuterSep}{0pt}
\newcommand*{\VertexMinSize}{0.6\DefaultUnit}
\newcommand*{\VertexLineWidth}{1pt}
\newcommand*{\VertexLineColor}{black}
\newcommand*{\VertexLineOpacity}{1}
\newcommand*{\VertexTextColor}{black}
\newcommand*{\VertexFillColor}{vertexfill}
\newcommand*{\VertexFillOpacity}{1}
\newcommand*{\VertexTextFont}{\scriptsize}%\tiny}
\newcommand*{\VertexTextRotation}{0}
\newcommand*{\VertexTextOpacity}{1}

%<--------------------------------------------------------------------------->
%      Edge
%<--------------------------------------------------------------------------->

\newcommand*{\EdgeArrow}{-latex}
\newcommand*{\EdgeLineWidth}{1.5pt}
\newcommand*{\EdgeColor}{black!75}
\newcommand*{\EdgeOpacity}{1}
\newcommand*{\EdgeTextFillColor}{white}
\newcommand*{\EdgeTextFillOpacity}{1}
\newcommand*{\EdgeInnerSep}{0pt}
\newcommand*{\EdgeOuterSep}{1pt}
\newcommand*{\EdgeTextRotation}{0}
\newcommand*{\EdgeTextOpacity}{1}
\newcommand*{\EdgeTextFont}{\scriptsize}

%<--------------------------------------------------------------------------->
%      Network
%<--------------------------------------------------------------------------->
\newcommand*{\NetworkLayerDistance}{-2}
\newcommand*{\xAngle}{-12}
\newcommand*{\xLength}{1}
\newcommand*{\yAngle}{37}
\newcommand*{\yLength}{1}
\newcommand*{\zAngle}{90}
\newcommand*{\zLength}{1}


\tikzset{edge canvas/.style={}}

\tikzset{multilayer 2d/.style={y={(0:1cm)},x={(90:1cm)},z={(90:0cm)},every
    node/.append style={transform shape},}}


\def\Origin{\draw [->] (0,0,0) -- (2,0,0) node [at end, right] {$y$};
\draw [->] (0,0,0) -- (0,2,0) node [at end, right] {$x$};
\draw [->] (0,0,0) -- (0,0,2) node [at end, left] {$z$};}


%=============================================================================
%      Predefined Styles
%=============================================================================

%<--------------------------------------------------------------------------->
%      Init Default Vertex Style
%<--------------------------------------------------------------------------->
\define@cmdkey [NW] {DVS} {Shape}{}
\define@cmdkey [NW] {DVS} {MinSize}{}
\define@cmdkey [NW] {DVS} {LineWidth}{}
\define@cmdkey [NW] {DVS} {LineColor}{}
\define@cmdkey [NW] {DVS} {LineOpacity}{}
\define@cmdkey [NW] {DVS} {FillColor}{}
\define@cmdkey [NW] {DVS} {FillOpacity}{}
\define@cmdkey [NW] {DVS} {TextColor}{}
\define@cmdkey [NW] {DVS} {TextFont}{}
\define@cmdkey [NW] {DVS} {TextRotation}{}
\define@cmdkey [NW] {DVS} {TextOpacity}{}
\define@cmdkey [NW] {DVS} {InnerSep}{}
\define@cmdkey [NW] {DVS} {OuterSep}{}
\presetkeys    [NW] {DVS} {Shape              = \VertexShape,
                           MinSize            = \VertexMinSize,
                           LineWidth          = \VertexLineWidth,
                           LineColor          = \VertexLineColor,
                           FillColor          = \VertexFillColor,
                           LineOpacity        = \VertexLineOpacity,
                           FillOpacity        = \VertexFillOpacity,
                           InnerSep           = \VertexInnerSep,
                           OuterSep           = \VertexOuterSep,
                           TextColor          = \VertexTextColor,
                           TextRotation       = \VertexTextRotation,
                           TextOpacity        = \VertexTextOpacity,
                           TextFont           = \VertexTextFont}{}

%<--------------------------------------------------------------------------->
%      Init Default Edge Style
%<--------------------------------------------------------------------------->
\define@cmdkey [NW] {DES} {Arrow}{}
\define@cmdkey [NW] {DES} {LineWidth}{}
\define@cmdkey [NW] {DES} {Color}{}
\define@cmdkey [NW] {DES} {Opacity}{}
\define@cmdkey [NW] {DES} {TextFillColor}{}
\define@cmdkey [NW] {DES} {TextFillOpacity}{}
\define@cmdkey [NW] {DES} {TextFont}{}
\define@cmdkey [NW] {DES} {TextRotation}{}
\define@cmdkey [NW] {DES} {TextOpacity}{}
\define@cmdkey [NW] {DES} {InnerSep}{}
\define@cmdkey [NW] {DES} {OuterSep}{}
\presetkeys    [NW] {DES} {Arrow              = \EdgeArrow,
                           LineWidth          = \EdgeLineWidth,
                           Color              = \EdgeColor,
                           Opacity            = \EdgeOpacity,
                           TextFillColor      = \EdgeTextFillColor,
                           TextFillOpacity    = \EdgeTextFillOpacity,
                           InnerSep           = \EdgeInnerSep,
                           OuterSep           = \EdgeOuterSep,
                           TextRotation       = \EdgeTextRotation,
                           TextOpacity        = \EdgeTextOpacity,
                           TextFont           = \EdgeTextFont}{}



%<--------------------------------------------------------------------------->
%      Init Default Coordinates 3D
%<--------------------------------------------------------------------------->
\define@cmdkey [NW] {COS} {xAngle}{}
\define@cmdkey [NW] {COS} {xLength}{}
\define@cmdkey [NW] {COS} {yAngle}{}
\define@cmdkey [NW] {COS} {yLength}{}
\define@cmdkey [NW] {COS} {zAngle}{}
\define@cmdkey [NW] {COS} {zLength}{}
\presetkeys    [NW] {COS} {xAngle             = \xAngle,
                           xLength            = \xLength,
                           yAngle             = \yAngle,
                           yLength            = \yLength,
                           zAngle             = \zAngle,
                           zLength            = \zLength}{}



%<--------------------------------------------------------------------------->
%      Default Style
%<--------------------------------------------------------------------------->

\newcommand*{\SetVertexStyle}[1][]{\NW@SetVertexStyleDefault[#1]}%
\def\NW@SetVertexStyleDefault[#1]{%
\setkeys[NW]{DVS}{#1}% 
\tikzset{VertexStyle/.style = {draw,
                               shape          = \cmdNW@DVS@Shape,
                               color          = \cmdNW@DVS@LineColor,
                               fill           = \cmdNW@DVS@FillColor,
                               inner sep      = \cmdNW@DVS@InnerSep,
                               outer sep      = \cmdNW@DVS@OuterSep,
                               minimum size   = \cmdNW@DVS@MinSize,
                               line width     = \cmdNW@DVS@LineWidth,
                               font           = \cmdNW@DVS@TextFont,
                               fill opacity   = \cmdNW@DVS@FillOpacity,
                               draw opacity   = \cmdNW@DVS@LineOpacity}}
\tikzset{LabelStyle/.style={   \cmdNW@DVS@TextColor,
                               font           = \cmdNW@DVS@TextFont,
                               rotate         = \cmdNW@DVS@TextRotation,
                               opacity        = \cmdNW@DVS@TextOpacity,}}
}%

\newcommand*{\SetEdgeStyle}[1][]{\NW@SetEdgeStyleDefault[#1]}%
\def\NW@SetEdgeStyleDefault[#1]{%
\setkeys[NW]{DES}{#1}% 
\tikzset{EdgeStyle/.style =   {\cmdNW@DES@Arrow,
                               line width     = \cmdNW@DES@LineWidth,
                               color          = \cmdNW@DES@Color,
                               opacity        = \cmdNW@DES@Opacity}}
\tikzset{EdgeLabelStyle/.style={circle,
                               fill           = \cmdNW@DES@TextFillColor,
                               fill opacity   = \cmdNW@DES@TextFillOpacity,
                               inner sep      = \cmdNW@DES@InnerSep,
                               outer sep      = \cmdNW@DES@OuterSep,
                               rotate         = \cmdNW@DES@TextRotation,
                               text opacity   = \cmdNW@DES@TextOpacity,
                               font           = \cmdNW@DES@TextFont}}
}%

\tikzset{
    multilayer/.code={%
      \ifthenelse{\equal{#1}{3d}}{
        \tikzset{edge canvas/.style={canvas is yx plane at z=0}}
        \tikzset{multilayer 3d}
      }{
        \tikzset{edge canvas/.style={}}
        \tikzset{multilayer 2d}
      }
    },
  }



\newcommand*{\SetCoordinates}[1][]{\NW@SetCoordinates[#1]}%
\def\NW@SetCoordinates[#1]{%
\setkeys[NW]{COS}{#1}% 
\tikzset{multilayer 3d/.style={
    y={(\cmdNW@COS@xAngle:\cmdNW@COS@xLength \DefaultUnit)},
    x={(\cmdNW@COS@yAngle:\cmdNW@COS@yLength \DefaultUnit)},
    z={(\cmdNW@COS@zAngle:\cmdNW@COS@zLength \DefaultUnit)},
    every node/.append style={transform shape},
 }}
%\tikzset{edge canvas/.style={canvas is yx plane at z=0}}
}%


%<--------------------------------------------------------------------------->
%      Apply default settings
%<--------------------------------------------------------------------------->

\SetCoordinates
\SetVertexStyle
\SetEdgeStyle


%<--------------------------------------------------------------------------->
%      Redefine settings
%<--------------------------------------------------------------------------->

\newcommand*{\SetLayerDistance}[1]{\renewcommand{\NetworkLayerDistance}{#1}}
\newcommand*{\SetDefaultUnit}[1]{\renewcommand{\DefaultUnit}{#1}}
\newcommand*{\SetDistanceScale}[1]{\renewcommand{\DistanceScale}{#1}}


%=============================================================================
%      Vertex and Edge creation
%=============================================================================

%<--------------------------------------------------------------------------->
%      Init Vertex
%<--------------------------------------------------------------------------->
\define@cmdkey  [NW] {vertex} {x}{}
\define@cmdkey  [NW] {vertex} {y}{}
\define@cmdkey  [NW] {vertex} {label}{}
\define@cmdkey  [NW] {vertex} {size}{}
\define@cmdkey  [NW] {vertex} {color}{}
\define@cmdkey  [NW] {vertex} {opacity}{}
\define@cmdkey  [NW] {vertex} {style}{}
\define@cmdkey  [NW] {vertex} {layer}{}
\define@boolkey [NW] {vertex} {RGB}[true]{}
\define@boolkey [NW] {vertex} {IdAsLabel}[true]{}
\define@boolkey [NW] {vertex} {NoLabel}[true]{}
\define@boolkey [NW] {vertex} {Math}[true]{}
\define@boolkey [NW] {vertex} {Network}[true]{}
\define@cmdkey  [NW] {vertex} {distance}{}
\define@cmdkey  [NW] {vertex} {position}{}
\presetkeys     [NW] {vertex} {Network = false,}{}


%<--------------------------------------------------------------------------->
%      Vertex
%<--------------------------------------------------------------------------->
\newcommand*{\Vertex}[1][]{\@vertex[#1]}%
\def\@vertex[#1]#2{%
    \setkeys[NW]{vertex}{#1}%
    % Check if Vertex is used in a network, if so no default settings are
    % necessary, otherwise default settings are applied. 
    \ifNW@vertex@Network
    \cmdNW@vertex@opacity
    \else
      \setkeys[NW]{vertex}{x          = {0},
                           y          = {0},
                           label      = {},
                           size       = {},
                           color      = {},
                           opacity    = {},
                           layer      = {},
                           style      = {},
                           NoLabel    = false,
                           IdAsLabel  = false,
                           Math       = false,
                           RGB        = false,
                           distance   = {0},
                           position   = {center},}
      \setkeys[NW]{vertex}{#1}%
    \fi
    \@@vertex{#2}%
}
\def\@@vertex#1{%
  \def\vstyle{VertexStyle}
  \begin{scope}
    % [
    % scale=1,yshift=0,every node/.append style={yslant=0.5,xslant=-1},yslant=0.5,xslant=-1
    % ]
    % If option NoLabel is true, no labels are printed in the network
    \ifNW@vertex@NoLabel
      \def\vertex@L{}%
      \def\vertex@Name{}%
    \else
      % if IdAsLabel is true, the label of the vertex is equal to the vertex id 
      \ifNW@vertex@IdAsLabel
        \def\vertex@Name{#1}
        \def\vertex@L{\vertex@Name}
      % Otherwise the label is equal to the label if it is non empty 
      \else
        \ifthenelse{\not\equal{\cmdNW@vertex@label}{}}{
          \def\vertex@L{\cmdNW@vertex@label}
          \def\vertex@Name{#1}
        }{
          \def\vertex@Name{#1}
          \def\vertex@L{}
        }
      \fi
    \fi
    % Check if Math is true, if so the label will be in math mode
    \ifNW@vertex@Math
      \def\vertex@Label{$\vertex@L$}%
    \else
      \def\vertex@Label{\vertex@L}%
    \fi
    % Check if the size of the vertex is redefined, if so the new style is used
    \ifthenelse{\not\equal{\cmdNW@vertex@size}{}}{
      \tikzset{LocalVertexSize/.style={minimum size = \cmdNW@vertex@size
          \DefaultUnit}}
    }{
      \tikzset{LocalVertexSize/.style={}}
    }
    % Check if the opacity of the vertex is redefined, if so the new style is used
    \ifthenelse{\not\equal{\cmdNW@vertex@opacity}{}}{
      \tikzset{LocalVertexOpacity/.style={fill opacity = \cmdNW@vertex@opacity}}
    }{
      \tikzset{LocalVertexOpacity/.style={}}
    }
    % Check if the color of the vertex is redefined, if so the new style is
    % used. If the option RGB is true, RGB values can be used to define the
    % color of the vertex entered in the form {R,G,B}. If RGB is not true the
    % default colors of tikz can be used (e.g. blue!50!green)
    \ifNW@vertex@RGB
      \ifthenelse{\not\equal{\cmdNW@vertex@color}{}}{
        \pgfutil@definecolor{LocalColor}{RGB}{\cmdNW@vertex@color}
        \tikzset{LocalVertexFill/.style={fill = LocalColor}}
      }{
        \tikzset{LocalVertexFill/.style={}}
      }
    \else
      \ifthenelse{\not\equal{\cmdNW@vertex@color}{}}{
        \tikzset{LocalVertexFill/.style={fill = \cmdNW@vertex@color}}
      }{
        \tikzset{LocalVertexFill/.style={}}
      }
    \fi
    % Define local style for the label
    \tikzset{LocalLabel/.style={label = {[LabelStyle, label
          distance=\cmdNW@vertex@distance]\cmdNW@vertex@position:\vertex@Label}}}
    \ifthenelse{\equal{\cmdNW@vertex@layer}{}}{
      \protected@edef\@tempa{%
        \noexpand\node[\vstyle,LocalVertexSize,LocalVertexOpacity,LocalVertexFill,LocalLabel,\cmdNW@vertex@style](#1)%
        at (\cmdNW@vertex@x,\cmdNW@vertex@y){}}%
      \@tempa;
    }{
      \begin{scope}[canvas is yx plane at z=(\cmdNW@vertex@layer-1)*\NetworkLayerDistance]
      \protected@edef\@tempa{%
        \noexpand\node[\vstyle,LocalVertexSize,LocalVertexOpacity,LocalVertexFill,LocalLabel,\cmdNW@vertex@style](#1)%
        at (\cmdNW@vertex@x*\DistanceScale\DefaultUnit,\cmdNW@vertex@y*\DistanceScale\DefaultUnit){}}%
      \@tempa;
      \end{scope}
    }
  \end{scope}
}

%<--------------------------------------------------------------------------->
%      Init Edge
%<--------------------------------------------------------------------------->
\define@cmdkey  [NW] {edge} {label}{}
\define@cmdkey  [NW] {edge} {lw}{}
\define@cmdkey  [NW] {edge} {color}{}
\define@cmdkey  [NW] {edge} {opacity}{}
\define@cmdkey  [NW] {edge} {style}{}
\define@boolkey [NW] {edge} {RGB}[true]{}
\define@boolkey [NW] {edge} {Math}[true]{}
\define@boolkey [NW] {edge} {Direct}[true]{}
\define@boolkey [NW] {edge} {Network}[true]{}
\define@cmdkey  [NW] {edge} {bend}{}
\define@cmdkey  [NW] {edge} {position}{}
\define@cmdkey  [NW] {edge} {distance}{}
\define@cmdkey  [NW] {edge} {loopsize}{}
\define@cmdkey  [NW] {edge} {loopposition}{}
\define@cmdkey  [NW] {edge} {loopshape}{}
\presetkeys     [NW] {edge} {Network    = false,}{}

%<--------------------------------------------------------------------------->
%      Edge
%<--------------------------------------------------------------------------->
\newcommand*{\Edge}[1][]{\@edge[#1]}%
\def\@edge[#1](#2)(#3){%
  \setkeys[NW]{edge}{#1}%
  % Check if Vertex is used in a network, if so no default settings are
  % necessary, otherwise default settings are applied. 
  \ifNW@edge@Network
    \cmdNW@edge@opacity
  \else
    \setkeys[NW]{edge}{label      = {},
                       lw         = {},
                       color      = {},
                       opacity    = {},
                       style      = {},
                       RGB        = false,
                       Math       = false,
                       Direct     = false,
                       bend       = {0},
                       loopsize  = {1\DefaultUnit},
                       position   = {},
                       loopposition= {0},
                       loopshape  = {90},
                       distance   = {.5}}
    \setkeys[NW]{edge}{#1}%
  \fi
  \def\estyle{EdgeStyle}
  \begin{scope}[edge canvas]
    % [
    % scale=1,yshift=0,every node/.append style={yslant=0.5,xslant=-1},yslant=0.5,xslant=-1
    % ]
    % Check if Direct is true, if so use default arrow style
    \ifNW@edge@Direct
      \tikzset{LocalArrow/.style={}}
    \else
      \tikzset{LocalArrow/.style={-}}
    \fi
    % Check if the line width of the vertex is redefined, if so the new style is
    % used
    \ifthenelse{\not\equal{\cmdNW@edge@lw}{}}{
      \tikzset{LocalEdgeLW/.style={line width = \cmdNW@edge@lw}}
    }{
      \tikzset{LocalEdgeLW/.style={}}
    }
    % Check if the opacity of the vertex is redefined, if so the new style is used
    \ifthenelse{\not\equal{\cmdNW@edge@opacity}{}}{
      \tikzset{LocalEdgeOpacity/.style={opacity = \cmdNW@edge@opacity}}
      \tikzset{LocalTextOpacity/.style={text opacity = \cmdNW@edge@opacity}}
    }{
      \tikzset{LocalEdgeOpacity/.style={}}
      \tikzset{LocalTextOpacity/.style={}}
    }
    % Check if the color of the vertex is redefined, if so the new style is
    % used. If the option RGB is true, RGB values can be used to define the
    % color of the vertex entered in the form {R,G,B}. If RGB is not true the
    % default colors of tikz can be used (e.g. blue!50!green)
    \ifNW@edge@RGB
      \ifthenelse{\not\equal{\cmdNW@edge@color}{}}{
        \pgfutil@definecolor{LocalColor}{RGB}{\cmdNW@edge@color}
        \tikzset{LocalEdgeColor/.style={color = LocalColor}}
      }{
        \tikzset{LocalEdgeColor/.style={}}
      }
    \else
      \ifthenelse{\not\equal{\cmdNW@edge@color}{}}{
        \tikzset{LocalEdgeColor/.style={color = \cmdNW@edge@color}}
      }{
        \tikzset{LocalEdgeColor/.style={}}
      }
    \fi
    % Check if Math is true, if so the label will be in math mode
    \ifNW@edge@Math
      \def\edge@L{$\cmdNW@edge@label$}%
    \else
      \def\edge@L{\cmdNW@edge@label}%
    \fi
    % Check if a label is assigned, if so create a label variable
    \ifthenelse{\not\equal{\cmdNW@edge@label}{}}{    \def\edge@Label{node[EdgeLabelStyle,LocalTextOpacity,pos=\cmdNW@edge@distance,\cmdNW@edge@position]{\edge@L}}
    }{
      \def\edge@Label{}
    }
    % Check if it is a self loop or a normal edge
    % Normal edge
    \ifthenelse{\not\equal{#2}{#3}}{
      \protected@edef\@tempa{%
        \noexpand\path[\estyle,LocalEdgeLW,LocalEdgeOpacity,LocalEdgeColor,LocalArrow,\cmdNW@edge@style] (#2) edge [bend left = \cmdNW@edge@bend] \edge@Label (#3)}%
      \@tempa;
    }{% Self loop
      \protected@edef\@tempa{%
        \noexpand\path[\estyle,LocalEdgeLW,LocalEdgeOpacity,LocalEdgeColor,LocalArrow,\cmdNW@edge@style]
        (#2) edge [in=-\cmdNW@edge@loopshape/2+\cmdNW@edge@loopposition,out=\cmdNW@edge@loopshape/2+\cmdNW@edge@loopposition,loop,distance=\cmdNW@edge@loopsize,] \edge@Label (#3)}%
      \@tempa;
    }
  \end{scope}
}


%=============================================================================
%      Vertices and Edges creation
%=============================================================================

%<--------------------------------------------------------------------------->
%      Init Vertices
%<--------------------------------------------------------------------------->
\define@cmdkey  [NW] {vertices} {layer}{}
\define@cmdkey  [NW] {vertices} {size}{}
\define@cmdkey  [NW] {vertices} {color}{}
\define@cmdkey  [NW] {vertices} {opacity}{}
\define@cmdkey  [NW] {vertices} {style}{}
\define@boolkey [NW] {vertices} {RGB}[true]{}
\define@boolkey [NW] {vertices} {IdAsLabel}[true]{}
\define@boolkey [NW] {vertices} {NoLabel}[true]{}
\define@boolkey [NW] {vertices} {Math}[true]{}
\presetkeys     [NW] {vertices} {layer     = {},
                                 opacity   = {},
                                 size      = {},
                                 color     = {},
                                 style     = {},
                                 RGB       = false,
                                 IdAsLabel = false,
                                 NoLabel   = false,
                                 Math      = false,}{}

\newcommand*{\setkeysexpanded}[2]{%
  \expandafter\setkeysexpandedaux\expandafter{#2}{#1}}
\newcommand*{\setkeysexpandedaux}[2]{%
  \setkeys[NW]{#2}{#1}}

% \newcommand*{\setkeysexpandedx}[2]{%
%   \expandafter\setkeysexpandedauxx\expandafter{#2}{#1}}
% \newcommand*{\setkeysexpandedauxx}[2]{%
%   \setkeys[NW]{#2}{#1}}



%<--------------------------------------------------------------------------->
%      Vertices
%<--------------------------------------------------------------------------->
\newcommand*{\Vertices}[1][]{\@vertices[#1]}%
\def\@vertices[#1]#2{%
    \setkeys[NW]{vertices}{#1}%
    \@@vertices{#2}%
}
\def\@@vertices#1{%
  % Check if data base already exist
  \DTLifdbexists{#1}{}{
    % create dummy data base to store name
    \DTLnewdb{#1}
    % delete existing vertices data base
    \DTLifdbexists{vertices}{
      \DTLgdeletedb{vertices}
    }{}
    % Load data file for vertices
    \DTLloaddb[noheader=false]{vertices}{#1}
  }
  % Define variables to store option values
  \def\vertex@Options{}%
  \def\vertex@id{}%
  \def\vertex@rgbValues{}%
  % Go through each row and create vertices
  \DTLforeach*{vertices}{}{%
    % reset storage variable to default values
    \edef\vertex@Options{x=0,y=0,label={},size={},color={},
      opacity={},layer={},style={},NoLabel=false,IdAsLabel=false,
      Math=false,RGB=false,distance={0},position={center}, }%
    \edef\vertex@rgbValues{}%
    % Go through each row element
    \DTLforeachkeyinrow{\thisValue}{
      \DTLifeq{\dtlkey}{id}{
        % Assign vertex id to storage variable
        \edef\vertex@id{\thisValue}%
      }{
        \DTLifeq{\dtlkey}{R}{
          \edef\vertex@rgbValues{\vertex@rgbValues \thisValue,}
         }{
           \DTLifeq{\dtlkey}{G}{
             \edef\vertex@rgbValues{\vertex@rgbValues \thisValue,}
             }{
               \DTLifeq{\dtlkey}{B}{
                 \edef\vertex@rgbValues{\vertex@rgbValues \thisValue,}
               }{
                 % Assign option to storage variable
                 \edef\vertex@Options{\vertex@Options \dtlkey=\thisValue,}
      }}}}
    }
    % Add general settings for the Vertex
    % NoLabel
    \ifNW@vertices@NoLabel
      \edef\vertex@Options{\vertex@Options NoLabel=true,}
    \fi
    % IdAsLabel
    \ifNW@vertices@IdAsLabel
      \edef\vertex@Options{\vertex@Options IdAsLabel=true,}
    \fi
    % Math
    \ifNW@vertices@Math
      \edef\vertex@Options{\vertex@Options Math=true,}
    \fi
    % RGB
    \ifNW@vertices@RGB
      \edef\vertex@Options{\vertex@Options RGB=true,color={\vertex@rgbValues},}
    \fi
    % opacity
    \ifthenelse{\not\equal{\cmdNW@vertices@opacity}{}}
    {
      \edef\vertex@Options{\vertex@Options opacity=\cmdNW@vertices@opacity,}
    }{}
    % size
    \ifthenelse{\not\equal{\cmdNW@vertices@size}{}}
    {
      \edef\vertex@Options{\vertex@Options size=\cmdNW@vertices@size,}
    }{}
    % color
    \ifthenelse{\not\equal{\cmdNW@vertices@color}{}}
    {
      \edef\vertex@Options{\vertex@Options color=\cmdNW@vertices@color,}
    }{}
    \ifthenelse{\not\equal{\cmdNW@vertices@style}{}}{
      \edef\vertex@Options{\vertex@Options style={\cmdNW@vertices@style},}
    }{}

    % Apply settings for the Vertex
    \setkeysexpanded{vertex}{\vertex@Options}%
    \ifthenelse{\not\equal{\cmdNW@vertices@layer}{}}{
      \ifthenelse{\equal{\cmdNW@vertices@layer}{\cmdNW@vertex@layer}}{
        \Vertex[Network]{\vertex@id}
      }{}
    }{
      \Vertex[Network]{\vertex@id}
    }
    % Create Vertex
  }
% Delete data base
% \DTLgdeletedb{#1}
}

%<--------------------------------------------------------------------------->
%      Init Edges
%<--------------------------------------------------------------------------->
\define@cmdkey  [NW] {edges} {layer}{}
\define@cmdkey  [NW] {edges} {vertices}{}
\define@cmdkey  [NW] {edges} {style}{}
\define@cmdkey  [NW] {edges} {lw}{}
\define@cmdkey  [NW] {edges} {color}{}
\define@cmdkey  [NW] {edges} {opacity}{}
\define@boolkey [NW] {edges} {RGB}[true]{}
\define@boolkey [NW] {edges} {Math}[true]{}
\define@boolkey [NW] {edges} {Direct}[true]{}
\define@boolkey [NW] {edges} {NoLabel}[true]{}
\define@boolkey [NW] {edges} {NotInBG}[true]{}
\presetkeys     [NW] {edges} {layer      = {},
                              vertices   = {},
                              style      = {},
                              lw         = {},
                              color      = {},
                              opacity    = {},
                              RGB        = false,
                              Math       = false,
                              Direct     = false,
                              NoLabel    = false,
                              NotInBG    = false,}{}

\newcommand{\shortcut}[1]{%
  \@tempswafalse
  \@for\next:=#1\do
    {\if@tempswa+\else\@tempswatrue\fi\textbf{\next}}%
}

\newcounter{LayerCounter}


\newcommand\myfunc[1]{\setcounter{LayerCounter}{0}\@for\tmp:=#1\do{
\stepcounter{LayerCounter}
\arabic{LayerCounter}-a-\textbf{\tmp}}
}


%<--------------------------------------------------------------------------->
%      Edges
%<--------------------------------------------------------------------------->
\newcommand*{\Edges}[1][]{\@edges[#1]}%
\def\@edges[#1]#2{%
    \setkeys[NW]{edges}{#1}%
    \@@edges{#2}%
}
\def\@@edges#1{%
\ifNW@edges@NotInBG
  \tikzset{InBG/.style={}}
\else
  \tikzset{InBG/.style={on background layer}}
\fi
\begin{scope}[InBG]
  % Check if data base already exist
  \DTLifdbexists{#1}{}{
    % create dummy data base to store name
    \DTLnewdb{#1}
    % delete existing vertices data base
    \DTLifdbexists{edges}{
      \DTLgdeletedb{edges}
    }{}
    % Load data file for vertices
    \DTLloaddb[noheader=false]{edges}{#1}
  }


  % % Load data file for vertices
  % \DTLloaddb[noheader=false]{#1}{#1}
  % Define variables to store option values
  \def\edge@Options{}%
  \def\edge@u{}%
  \def\edge@v{}%
  \def\edge@u@layer{}%
  \def\edge@v@layer{}%
  \def\edge@rgbValues{}%
  \def\u@layer{}%
  \def\v@layer{}%
  %
  % Assign where the edges are drawn from to
  \ifthenelse{\not\equal{\cmdNW@edges@layer}{}}{
    % set layer count back to 0
    \setcounter{LayerCounter}{0}
    \@for\tmp:=\cmdNW@edges@layer\do{
      \stepcounter{LayerCounter}
      \ifthenelse{\value{LayerCounter}=1}{
        \edef\u@layer{\tmp}%
      }{
        \edef\v@layer{\tmp}%
      }
    }
  }{}
  % Go through each row and create edges
  \DTLforeach*{edges}{}{%
    % reset storage variable to default values
    \edef\edge@Options{label = {}, lw = {}, color = {}, opacity = {}, style =
      {}, RGB = false, Math = false, Direct = false, bend = {0}, loopsize =
      {1\DefaultUnit}, position = {}, loopposition = {0}, loopshape = {90}, distance = {.5},}
  \edef\edge@rgbValues{}%
    % Go through each row element
    \DTLforeachkeyinrow{\thisValue}{
      \DTLifeq{\dtlkey}{u}{
        % Assign edge id to storage variable
        \edef\edge@u{\thisValue}%
      }{
        \DTLifeq{\dtlkey}{v}{
          \edef\edge@v{\thisValue}%
          }{
            \DTLifeq{\dtlkey}{R}{
              \edef\edge@rgbValues{\edge@rgbValues \thisValue,}
            }{
              \DTLifeq{\dtlkey}{G}{
                \edef\edge@rgbValues{\edge@rgbValues \thisValue,}
              }{
                \DTLifeq{\dtlkey}{B}{
                  \edef\edge@rgbValues{\edge@rgbValues \thisValue,}
                }{
                  % Assign option to storage variable
                  \edef\edge@Options{\edge@Options \dtlkey=\thisValue,}
                }}}}}
    }
    % Add general settings for the Edges
    % NoLabel
    \ifNW@edges@NoLabel
      \edef\edge@Options{\edge@Options label={},}
    \fi
    % Direct
    \ifNW@edges@Direct
      \edef\edge@Options{\edge@Options Direct=true,}
    \fi
    % Math
    \ifNW@edges@Math
      \edef\edge@Options{\edge@Options Math=true,}
    \fi
    % RGB
    \ifNW@edges@RGB
      \edef\edge@Options{\edge@Options RGB=true,color={\edge@rgbValues},}
    \fi
    \ifthenelse{\not\equal{\cmdNW@edges@style}{}}{
      \edef\edge@Options{\edge@Options style={\cmdNW@edges@style},}
    }{}
    % lw
    \ifthenelse{\not\equal{\cmdNW@edges@lw}{}}
    {
      \edef\edge@Options{\edge@Options lw=\cmdNW@edges@lw,}
    }{}
    % color
    \ifthenelse{\not\equal{\cmdNW@edges@color}{}}
    {
      \edef\edge@Options{\edge@Options color=\cmdNW@edges@color,}
    }{}
    % opacity
    \ifthenelse{\not\equal{\cmdNW@edges@opacity}{}}
    {
      \edef\edge@Options{\edge@Options opacity=\cmdNW@edges@opacity,}
    }{}


    % Apply settings for the Edge
    \setkeysexpanded{edge}{\edge@Options}%
    % Create Edge
    \ifthenelse{\equal{\cmdNW@edges@layer}{}}{
      \Edge[Network](\edge@u)(\edge@v)
    }{
      \ifthenelse{\not\equal{\cmdNW@edges@vertices}{}}{
        \DTLifdbexists{vertices}{
          \DTLgdeletedb{vertices}
        }{}
        % Load data file for vertices
        \DTLloaddb[noheader=false]{vertices}{\cmdNW@edges@vertices}      
      }{}
      % find assigned layer to the used vertices
      \DTLforeach*{vertices}{\id=id,\layer=layer}{%
        \ifthenelse{\equal{\id}{\edge@u}}{
          \edef\edge@u@layer{\layer}%
          \dtlbreak
        }{}
      }
      \DTLforeach*{vertices}{\id=id,\layer=layer}{%
        \ifthenelse{\equal{\id}{\edge@v}}{
          \edef\edge@v@layer{\layer}%
          \dtlbreak
        }{}
      }
      % if the edge is an intra layer edge
      \ifthenelse{\equal{\u@layer}{\v@layer}}{
        \ifthenelse{\equal{\u@layer}{\edge@u@layer}}{
          \ifthenelse{\equal{\v@layer}{\edge@v@layer}}{
            \Edge[Network](\edge@u)(\edge@v)
          }{}
        }{}
      }{
        \ifthenelse{\equal{\u@layer}{\edge@u@layer}}{
          \ifthenelse{\equal{\v@layer}{\edge@v@layer}}{
            \Edge[Network](\edge@u)(\edge@v)
          }{}
        }{}
        \ifthenelse{\equal{\v@layer}{\edge@u@layer}}{
          \ifthenelse{\equal{\u@layer}{\edge@v@layer}}{
            \Edge[Network](\edge@u)(\edge@v)
          }{}
        }{}

      }

    }
  }
\end{scope}
% Delete data base
% \DTLgdeletedb{#1}
}


%<--------------------------------------------------------------------------->
%      Init Layer
%<--------------------------------------------------------------------------->
\define@cmdkey  [NW] {layer} {layer}{}
\define@cmdkey  [NW] {layer} {z}{}
\define@cmdkey  [NW] {layer} {opacity}{}
\presetkeys     [NW] {layer} {layer   = {1},
                              opacity = {},
                              z       = {},}{}

%<--------------------------------------------------------------------------->
%      Layer
%<--------------------------------------------------------------------------->
%\def\@layer{canvas is yx plane at z=-3,}

\def\@layer[#1]#2{
\setkeys[NW]{layer}{#1}
\ifthenelse{\not\equal{\cmdNW@layer@z}{}}{
  \tikzset{LocalLayerZ/.style={canvas is yx plane at z=\cmdNW@layer@z}}
}{
  \tikzset{LocalLayerZ/.style={canvas is yx plane at z=(\cmdNW@layer@layer-1)*\NetworkLayerDistance}}
}
\ifthenelse{\not\equal{\cmdNW@layer@opacity}{}}{
  \tikzset{LocalLayerOpacity/.style={fill opacity = \cmdNW@layer@opacity}}
}{
  \tikzset{LocalLayerOpacity/.style={}}
}
\begin{scope}[LocalLayerZ,LocalLayerOpacity]
}
%\newcommand*{\Layer}[1][]{\@layer[#1]}%
\newenvironment{Layer}[1][]{\@layer[#1]1}{\end{scope}}
%\def\@layer[#1]#2{}
% \newcommand*{\Edges}[1][]{\@edges[#1]}%
% \def\@edges[#1]#2{%
%     \setkeys[NW]{edges}{#1}%
%     \@@edges{#2}%
% }
% \def\@@edges#1{%



\endinput
%=============================================================================
% eof
%
% Local Variables:
% mode: latex
% mode: flyspell
% mode: auto-fill
% fill-column: 80
% TeX-master: t
% End:
